home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume5 / tracer < prev    next >
Encoding:
Text File  |  1989-02-03  |  26.5 KB  |  1,012 lines

  1. Path: xanth!nic.MR.NET!hal!ncoast!allbery
  2. From: sid@chinet.UUCP (Sid Grange)
  3. Newsgroups: comp.sources.misc
  4. Subject: v05i046: ray tracing program for 3b1
  5. Message-ID: <12883@ncoast.UUCP>
  6. Date: 9 Nov 88 03:39:27 GMT
  7. Sender: allbery@ncoast.UUCP
  8. Reply-To: sid@chinet.UUCP (Sid Grange)
  9. Lines: 1000
  10. Approved: allbery@ncoast.UUCP
  11.  
  12. Posting-number: Volume 5, Issue 46
  13. Submitted-by: "Sid Grange" <sid@chinet.UUCP>
  14. Archive-name: tracer
  15.  
  16. [The author claims that it should be portable to other graphical Un*x systems.
  17. Since I don't have one handy, I've no way to test that.  ++bsa]
  18.  
  19. #! /bin/sh
  20. # This is a shell archive.  Remove anything before this line, then unpack
  21. # it by saving it into a file and typing "sh file".  To overwrite existing
  22. # files, type "sh file -c".  You can also feed this as standard input via
  23. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  24. # will see the following message at the end:
  25. #        "End of shell archive."
  26. # Contents:  Makefile README.DOC README.HAK bdata.i conv.c extern.h
  27. #   find.c g_bal.c g_bod.c macros.h refract.c rtd.h shade.c support.c
  28. #   tracer.c
  29. # Wrapped by sid@chinet on Mon Feb  8 20:03:07 1988
  30. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  31. if test -f Makefile -a "${1}" != "-c" ; then 
  32.   echo shar: Will not over-write existing file \"Makefile\"
  33. else
  34. echo shar: Extracting \"Makefile\" \(536 characters\)
  35. sed "s/^X//" >Makefile <<'END_OF_Makefile'
  36. Xtracer: tracer.o shade.o find.o support.o refract.o g_bod.o g_bal.o
  37. X    cc tracer.o shade.o find.o support.o refract.o g_bod.o g_bal.o -lm -o tracer
  38. Xfind.o: find.c rtd.h extern.h macros.h
  39. X    cc -c find.c 
  40. Xshade.o: shade.c rtd.h extern.h macros.h
  41. X    cc -c shade.c 
  42. Xsupport.o: support.c rtd.h extern.h
  43. X    cc -c support.c 
  44. Xtracer.o: tracer.c rtd.h bdata.i macros.h
  45. X    cc -c tracer.c  
  46. Xrefract.o: refract.c rtd.h extern.h macros.h
  47. X    cc -c refract.c  
  48. Xg_bod.o: g_bod.c extern.h macros.h
  49. X    cc -c g_bod.c  
  50. Xg_bal.o: g_bal.c extern.h rtd.h
  51. X    cc -c g_bal.c  
  52. END_OF_Makefile
  53. if test 536 -ne `wc -c <Makefile`; then
  54.     echo shar: \"Makefile\" unpacked with wrong size!
  55. fi
  56. # end of overwriting check
  57. fi
  58. if test -f README.DOC -a "${1}" != "-c" ; then 
  59.   echo shar: Will not over-write existing file \"README.DOC\"
  60. else
  61. echo shar: Extracting \"README.DOC\" \(2252 characters\)
  62. sed "s/^X//" >README.DOC <<'END_OF_README.DOC'
  63. X
  64. X
  65. X
  66. XTRACER(99)                  FRITZZ GRAPHICS            TRACER(99)
  67. X
  68. X
  69. X
  70. XNAME
  71. X     tracer- run a simple ray tracing procedure
  72. X
  73. XSYNOPSIS
  74. X     tracer -o [filename] -i [filename] -s <filename> -S<number>
  75. X
  76. XDESCRIPTION
  77. X     Tracer is a program developed originally to study how
  78. X     ray tracing works, and was later modified to the present state
  79. X     to make it more compatible for animated film production.
  80. X
  81. X     It is capable of depicting a number of balls (up to 150)
  82. X     and a plane that is covered with a tiling of any bitmapped picture.
  83. X
  84. X
  85. XOPTIONS
  86. X     -o Chooses the output data file. If no argument is givin, stdout
  87. X        is used. If the option is not used the default is data.dis.
  88. X
  89. X     -i Chooses the input (ball) data file. If no argument is given, stdin
  90. X        is used. If the option is not used the default is bdata.i.
  91. X     -s Chooses the file containing the tiling bitmap. It requires an
  92. X        an argument. If the option is not used the default is pat.def.
  93. X
  94. X     -S Chooses contrast of the pattern. 0.0 is no contrast, 1.0 is maximum
  95. X        contrast. 1.0 is the default. (useful for fading during animation)
  96. X
  97. XPROGRAM NOTES
  98. X     This program generates a file containing a header with x and y sizes,
  99. X     followed by the data in 8-bit greyscale, one pixel to a character, in 
  100. X     scanlines.
  101. X     There are two neccessary input files: ball data, and a pattern bitmap.
  102. X     The tiling bitmap can be digitized data, it must be in the form of 
  103. X     scan lines no longer than 512 bytes followed by newlines.
  104. X     the ball data is of the following form:
  105. X
  106. X     x y z rad ior refract reflect diffuse ambient
  107. X
  108. X     on each line where x y & z are the coordinates of the center of 
  109. X     the ball, rad is the radius of the ball, ior is the index of refraction
  110. X     for translucent materials (index of refraction for glass is about 1.5)
  111. X     the last four numbers determine how much of each atrribute is used.
  112. X     Thus a pure silver ball would have 0.0 1.0 0.0 0.0 as the last numbers,
  113. X     and a pure glass ball would have 1.0 0.0 0.0 0.0 .
  114. X
  115. X
  116. XFILES
  117. X     ./bdata.i    default ball data
  118. X     ./pat.def  default floor pattern
  119. X     ./data.dis default output file
  120. X
  121. XBUGS
  122. X     As with any good software, the complexity of this program hides 
  123. X     all bugs.
  124. X
  125. END_OF_README.DOC
  126. if test 2252 -ne `wc -c <README.DOC`; then
  127.     echo shar: \"README.DOC\" unpacked with wrong size!
  128. fi
  129. # end of overwriting check
  130. fi
  131. if test -f README.HAK -a "${1}" != "-c" ; then 
  132.   echo shar: Will not over-write existing file \"README.HAK\"
  133. else
  134. echo shar: Extracting \"README.HAK\" \(1259 characters\)
  135. sed "s/^X//" >README.HAK <<'END_OF_README.HAK'
  136. X***** A Hackers Guide to Tracer *****
  137. Xtracer consists of a bunch of files containing a program that does 
  138. Xray tracing (No shit sherlock).
  139. XThes files are as follows:
  140. Xtracer.c:    main() sets up the initial rays and stores values
  141. X        in a file. booboo prints an error message and quits.
  142. Xshade.c:    shade() calculates the intensity returned by a ray. It is
  143. X         recursive, and also makes a call to refract().
  144. Xrefract.c:    The most difficult part of the program. This file contains
  145. X        refract(), inside(), refk() and getcapt().
  146. X        and these do all the refraction calculations.
  147. Xfind.c:        contains find(),findo() (for when a ray is inside a ball)
  148. X        and shadow() and finds() for shadows.
  149. Xsupport.c:    supportive subroutines. right now only contains mt_vec
  150. X        as all the others were either discarded or converted to 
  151. X        macros.
  152. Xg_bal.c        g_bal() gets the ball data and points bl[] at them.
  153. Xg_bod.c        g_bod() loads the floor pattern into suzie.
  154. X
  155. Xmacros.h    contains all the macro definitions. Definitely to be looked at.
  156. Xrtd.h        header file containing all the structure definitions.
  157. Xextern.h    keeps track of all global variables used through the program.
  158. X
  159. Xbdata.i        sample ball data file.
  160. X
  161. Xpat.def \
  162. Xcheck.pat\
  163. Xsusie.pat >-    sample pattern files. (susie is not for the purient).
  164. Xship.pat /
  165. X
  166. END_OF_README.HAK
  167. if test 1259 -ne `wc -c <README.HAK`; then
  168.     echo shar: \"README.HAK\" unpacked with wrong size!
  169. fi
  170. # end of overwriting check
  171. fi
  172. if test -f bdata.i -a "${1}" != "-c" ; then 
  173.   echo shar: Will not over-write existing file \"bdata.i\"
  174. else
  175. echo shar: Extracting \"bdata.i\" \(213 characters\)
  176. sed "s/^X//" >bdata.i <<'END_OF_bdata.i'
  177. X
  178. X-30.0 10.0 400.0 50.0 0.0 0.0 0.0 0.9 0.1
  179. X210.0 175.0 400.0 50.0 0.0 0.0 0.3 0.6 0.1
  180. X40.0 110.0 450.0 50.0 0.0 0.0 0.6 0.3 0.1
  181. X140.0 65.0 450.0 50.0 0.0 0.0 0.9 0.0 0.1
  182. X
  183. X220.0 70.0 100.0 60.0 1.4 0.9 0.0 0.0 0.1
  184. END_OF_bdata.i
  185. if test 213 -ne `wc -c <bdata.i`; then
  186.     echo shar: \"bdata.i\" unpacked with wrong size!
  187. fi
  188. # end of overwriting check
  189. fi
  190. if test -f conv.c -a "${1}" != "-c" ; then 
  191.   echo shar: Will not over-write existing file \"conv.c\"
  192. else
  193. echo shar: Extracting \"conv.c\" \(824 characters\)
  194. sed "s/^X//" >conv.c <<'END_OF_conv.c'
  195. X#include <stdio.h>
  196. X#include <tam.h>
  197. X#include <fcntl.h>
  198. X  
  199. Xextern errno;
  200. X
  201. Xmain(argc, argv)
  202. Xint argc;
  203. Xchar *argv[];
  204. X
  205. X{
  206. X  char *malloc();
  207. X  char *cd,*d;
  208. X  short *bm,*c;
  209. X  int fd, cont;
  210. X register int a,b;
  211. X
  212. X    cont = 60; 
  213. X/*    if((argc == 2) && (atoi(argv[1]) >1) && (atoi(argv[1]) <100))
  214. X        cont = atoi(argv[1]);*/
  215. X    if ((fd=open(argv[1],O_RDONLY|O_NDELAY))==0) {
  216. X      fprintf("couldn't open %s for read\n", argv[1]);
  217. X      exit(-1);
  218. X    }
  219. X    if(lseek(fd,8,0)<0)
  220. X      exit(-1);
  221. X    cd=malloc(134400);
  222. X    if(read(fd,cd,134400)!=134400)
  223. X      exit(-1);
  224. X    bm=malloc(14974);
  225. X    c=bm+7487;
  226. X    for(a=287;a>=0;a--) {
  227. X      d=a*420+cd;
  228. X      for(b=415;b>=0;b--) {
  229. X        if(!(b&15))
  230. X          c-=1;
  231. X        *c=(*c<<1)|(*(d+b)>60);
  232. X      }
  233. X    }
  234. X    cd=bm;
  235. X    a = 0;
  236. X    while(a++ != 14974)
  237. X        fprintf(stdout, "%c", *cd++);
  238. X}
  239. END_OF_conv.c
  240. if test 824 -ne `wc -c <conv.c`; then
  241.     echo shar: \"conv.c\" unpacked with wrong size!
  242. fi
  243. # end of overwriting check
  244. fi
  245. if test -f extern.h -a "${1}" != "-c" ; then 
  246.   echo shar: Will not over-write existing file \"extern.h\"
  247. else
  248. echo shar: Extracting \"extern.h\" \(130 characters\)
  249. sed "s/^X//" >extern.h <<'END_OF_extern.h'
  250. Xextern double suzie[300][300],sam;
  251. Xextern struct ball *bl[];
  252. Xextern struct sphere ls;
  253. Xextern int level,nob;
  254. Xextern int xsue,ysue;
  255. END_OF_extern.h
  256. if test 130 -ne `wc -c <extern.h`; then
  257.     echo shar: \"extern.h\" unpacked with wrong size!
  258. fi
  259. # end of overwriting check
  260. fi
  261. if test -f find.c -a "${1}" != "-c" ; then 
  262.   echo shar: Will not over-write existing file \"find.c\"
  263. else
  264. echo shar: Extracting \"find.c\" \(1942 characters\)
  265. sed "s/^X//" >find.c <<'END_OF_find.c'
  266. X#include <math.h>
  267. X#include "rtd.h"
  268. X#include "extern.h"
  269. X#include "macros.h"
  270. X
  271. X
  272. Xdouble  findo (m, s) /* finds where a ray inside the ball exits. */
  273. Xstruct mat *m;
  274. Xstruct sphere  *s;
  275. X{
  276. X/* foops id the rotated position vector. */
  277. X    struct vector   foops;
  278. X    double  t;
  279. X    MTV (foops, (*m), s -> cent);
  280. X/* see if it hits the ball (it better)*/
  281. X    t = s -> rad * s -> rad - foops.y * foops.y - foops.z * foops.z;
  282. X    if (t > 0)
  283. X    t = foops.x + sqrt (t);
  284. X    else
  285. X    t = 0;
  286. X/* return how far along the ray you were when you hit */
  287. X    return (t);
  288. X}
  289. X
  290. Xdouble  find (m, s)/* finds whether a ray hits a ball*/
  291. Xstruct mat *m;
  292. Xstruct sphere  *s;
  293. X{
  294. X    struct vector   foops;
  295. X    double  t;
  296. X    MTV (foops, (*m), s -> cent);
  297. X    t = s -> rad * s -> rad - foops.y * foops.y - foops.z * foops.z;
  298. X    if (t > 0)
  299. X    t = foops.x - sqrt (t);
  300. X    else
  301. X    t = 0;
  302. X    return (t);
  303. X}
  304. X
  305. Xdouble  finds (m, s)/* finds if a ball is between a point and a 
  306. X            lightsource. Returns how obscuring the ball is */
  307. Xstruct mat *m;
  308. Xstruct sphere  *s;
  309. X{
  310. X    struct vector   foops;
  311. X    double  t;
  312. X    MTV (foops, (*m), s -> cent);
  313. X    t = s -> rad - sqrt (foops.y * foops.y + foops.z * foops.z);
  314. X    if (t > 0)
  315. X    t = t / foops.x;
  316. X    else
  317. X    t = 0;
  318. X    return (t);
  319. X}
  320. X
  321. X
  322. X
  323. X
  324. Xdouble  shadow (p)/* finds if a point is in a shadow, or if it is on edge */
  325. Xstruct vector  *p;
  326. X{
  327. X    struct mat  trans;
  328. X    struct sphere   ss;
  329. X    struct vector   d;
  330. X    int     c,
  331. X            i;
  332. X    double  l,
  333. X            k,
  334. X            x,
  335. X            y,
  336. X            z,
  337. X            finds ();
  338. X    l = 0.0;
  339. X    c = -1;
  340. X    SV (d, ls.cent, (*p));
  341. X    d.l = LEN (d);
  342. X    d.xzl = XZL (d);
  343. X    mt (&(d), &trans);
  344. X
  345. X    for (i = 0; i < nob; i++) {
  346. X    ss.rad = bl[i] -> s.rad;
  347. X    SV (ss.cent, bl[i] -> s.cent, (*p));
  348. X    if ((k = finds (&trans, &ss)) > l) {
  349. X        c = i;
  350. X        l = k;
  351. X    }
  352. X    }
  353. X    if (c == -1)
  354. X    k = 200.0;
  355. X    else {
  356. X    k = 1.0 - l / ((ls.rad) / (d.l));
  357. X    if (k < 0.0)
  358. X        k = 0.0;
  359. X    k *= 200.0;
  360. X    }
  361. X    return (k);
  362. X}
  363. END_OF_find.c
  364. if test 1942 -ne `wc -c <find.c`; then
  365.     echo shar: \"find.c\" unpacked with wrong size!
  366. fi
  367. # end of overwriting check
  368. fi
  369. if test -f g_bal.c -a "${1}" != "-c" ; then 
  370.   echo shar: Will not over-write existing file \"g_bal.c\"
  371. else
  372. echo shar: Extracting \"g_bal.c\" \(652 characters\)
  373. sed "s/^X//" >g_bal.c <<'END_OF_g_bal.c'
  374. X#include <stdio.h>
  375. X#include "rtd.h"
  376. X#include "extern.h"
  377. Xg_bal (df)
  378. XFILE * df;
  379. X{
  380. X    int     i;
  381. X    double  x,
  382. X            y,
  383. X            z,
  384. X            r,
  385. X            ior,
  386. X            rfr,
  387. X            rfl,
  388. X            dif,
  389. X            amb;
  390. X    for (i = 0;
  391. X        fscanf (df, "%F %F %F %F %F %F %F %F %F",
  392. X        &x, &y, &z, &r, &ior, &rfr, &rfl, &dif, &amb) != EOF;
  393. X        i++) {
  394. X    bl[i] = (struct ball   *) malloc (sizeof (struct ball));
  395. X    bl[i] -> s.cent.x = x;
  396. X    bl[i] -> s.cent.y = y;
  397. X    bl[i] -> s.cent.z = z;
  398. X    bl[i] -> s.rad = r;
  399. X    bl[i] -> ior = ior;
  400. X    bl[i] -> rfr = rfr;
  401. X    bl[i] -> rfl = rfl;
  402. X    bl[i] -> dif = dif;
  403. X    bl[i] -> amb = amb;
  404. X    }
  405. X    return (i);
  406. X}
  407. X
  408. END_OF_g_bal.c
  409. if test 652 -ne `wc -c <g_bal.c`; then
  410.     echo shar: \"g_bal.c\" unpacked with wrong size!
  411. fi
  412. # end of overwriting check
  413. fi
  414. if test -f g_bod.c -a "${1}" != "-c" ; then 
  415.   echo shar: Will not over-write existing file \"g_bod.c\"
  416. else
  417. echo shar: Extracting \"g_bod.c\" \(595 characters\)
  418. sed "s/^X//" >g_bod.c <<'END_OF_g_bod.c'
  419. X#include <stdio.h>
  420. X#include <math.h>
  421. X#include "extern.h"
  422. X#include "macros.h"
  423. X
  424. X
  425. Xg_bod (f)
  426. XFILE * f;
  427. X{
  428. X    int     k,
  429. X            x;
  430. X    double  big = 0.0,
  431. X            little = HUGE;
  432. X    char    buf[512];
  433. X
  434. X
  435. X    for (ysue = 0;; ysue++) {
  436. X    if (fgets (buf, 512, f) == NULL)
  437. X        break;
  438. X    xsue = strlen (buf) - 1;
  439. X    for (x = 0; x < xsue; x++) {
  440. X        k = buf[x];
  441. X        suzie[x][ysue] = (double) k;
  442. X        if (big < k)
  443. X        big = k;
  444. X        if (little > k)
  445. X        little = k;
  446. X    }
  447. X    }
  448. X    big = big - little;
  449. X    for (k = 0; k < ysue; k++)
  450. X    for (x = 0; x < xsue; x++)
  451. X        suzie[x][k] = (suzie[x][k] - little) / big;
  452. X}
  453. END_OF_g_bod.c
  454. if test 595 -ne `wc -c <g_bod.c`; then
  455.     echo shar: \"g_bod.c\" unpacked with wrong size!
  456. fi
  457. # end of overwriting check
  458. fi
  459. if test -f macros.h -a "${1}" != "-c" ; then 
  460.   echo shar: Will not over-write existing file \"macros.h\"
  461. else
  462. echo shar: Extracting \"macros.h\" \(1116 characters\)
  463. sed "s/^X//" >macros.h <<'END_OF_macros.h'
  464. X/* some of the most important stuff in the program */
  465. X#define DOT(v1,v2) (v1.x*v2.x+v1.y*v2.y+v1.z*v2.z)
  466. X/* returns dot product of two vectors */
  467. X#define LN2(v)       (DOT(v,v))
  468. X/* returns the square of the length of a vector */
  469. X#define LEN(v)       sqrt(LN2(v))
  470. X/* guess */
  471. X#define XZL(v)       sqrt(v.x*v.x+v.z*v.z)
  472. X/* returns the component in the xz plane of a vector */
  473. X#define SCMLT(sc,vct) vct.x*= sc;vct.y*= sc;vct.z*= sc;vct.l*= sc;
  474. X/* multiplies a vetor by a scalar */
  475. X#define MV(a,b,c,v)   v.x= a;v.y= b;v.z= c;
  476. X/* makes a vector. wouldn't need this with c++ */
  477. X#define SV(t,u,v)  t.x=u.x-v.x;t.y=u.y-v.y;t.z=u.z-v.z;
  478. X/*subtract vector t=u-v */
  479. X#define AV(t,u,v)  t.x=u.x+v.x;t.y=u.y+v.y;t.z=u.z+v.z;
  480. X/* add vector t=u+v */
  481. X#define MTV(v1,m,v2) MV(DOT(m.x,v2),DOT(m.y,v2),DOT(m.z,v2),v1)
  482. X/* multiply transpose matrix by vector. v1=m*v2 */
  483. X
  484. X#define LEVEL 5/* levels of recursion */
  485. X#define RLEV  3/*don't want as many inside the ball, takes forever as it is*/
  486. X
  487. X#define XMIN 10.0
  488. X#define XMAX 220.0
  489. X#define YMIN 10.0
  490. X#define YMAX 170.0
  491. X/* window size,  virtual units */
  492. X#define SCALE  2.0
  493. X/* maginification factor */
  494. END_OF_macros.h
  495. if test 1116 -ne `wc -c <macros.h`; then
  496.     echo shar: \"macros.h\" unpacked with wrong size!
  497. fi
  498. # end of overwriting check
  499. fi
  500. if test -f refract.c -a "${1}" != "-c" ; then 
  501.   echo shar: Will not over-write existing file \"refract.c\"
  502. else
  503. echo shar: Extracting \"refract.c\" \(2965 characters\)
  504. sed "s/^X//" >refract.c <<'END_OF_refract.c'
  505. X#include <math.h>
  506. X#include "rtd.h"
  507. X#include "macros.h"
  508. X#include "extern.h"
  509. X
  510. Xint    rlev;
  511. Xint     refract (r, bll)
  512. Xstruct ray *r;
  513. Xstruct ball *bll;
  514. X{
  515. X    struct vector   new,
  516. X                    norm;
  517. X    struct mat  trans;
  518. X    struct ray  ir;
  519. X    double  l,
  520. X            refk (), getcapt (), capt, inside ();
  521. X    double  stupid;
  522. X    struct sphere   ss;
  523. X
  524. X    SV (norm, r -> org, bll -> s.cent);
  525. X    norm.l = bll-> s.rad;
  526. X
  527. X    capt = getcapt (&norm, &(r -> dir), bll -> ior);
  528. X
  529. X
  530. X/* get the addition factor for the normal for refraction*/
  531. X    stupid = refk (&(norm), &(r -> dir), bll -> ior);
  532. X    SCMLT (stupid, norm);
  533. X
  534. X    AV (ir.dir, r -> dir, norm);
  535. X    MV (r -> org.x, r -> org.y, r -> org.z, ir.org);
  536. X
  537. X/* now get it for reflection */
  538. X    SV (norm, r -> org, bll -> s.cent);
  539. X    norm.l = bll -> s.rad;
  540. X    SCMLT (1.0 / norm.l, norm);
  541. X    stupid = 2.0 * DOT (norm, r -> dir);
  542. X    SCMLT (stupid, norm);
  543. X    SV (r -> dir, r -> dir, norm);
  544. X
  545. X    return ((int) ((1.0 - capt) * (double) shade (r) + ((capt) * inside (&ir, bll))));
  546. X}
  547. X
  548. Xdouble  inside (r, bll)
  549. Xstruct ray *r;
  550. Xstruct ball *bll;
  551. X{
  552. X    struct vector   new,
  553. X                    norm;
  554. X    struct mat  trans;
  555. X    struct ray  er;
  556. X    double  findo (), lght, l, refk (), getcapt (), capt;
  557. X    double  stupid;
  558. X    struct sphere   ss;
  559. X
  560. X
  561. X    if (++rlev < RLEV) {
  562. X    r -> dir.l = LEN (r -> dir);
  563. X    r -> dir.xzl = XZL (r -> dir);
  564. X    mt (&(r -> dir), &trans);
  565. X    ss.rad = bll -> s.rad;
  566. X    SV (ss.cent, bll -> s.cent, r -> org);
  567. X
  568. X    l = findo (&trans, &ss);
  569. X    MV (l * trans.x.x, l * trans.x.y, l * trans.x.z, new);
  570. X    AV (er.org, r -> org, new);
  571. X    AV (r -> org, r -> org, new);
  572. X    SV (norm, er.org, bll -> s.cent);
  573. X
  574. X    norm.l = bll -> s.rad;
  575. X    capt = getcapt (&norm, &(r -> dir), 1.0 / bll -> ior);
  576. X
  577. X    stupid = refk (&norm, &(r -> dir), 1.0 / bll -> ior);
  578. X    SCMLT (stupid, norm);
  579. X    AV (er.dir, norm, r -> dir);
  580. X
  581. X    SCMLT (1.0 / norm.l, norm);
  582. X    stupid = 2.0 * DOT (norm, r -> dir);
  583. X    SCMLT (stupid, norm);
  584. X    SV (r -> dir, r -> dir, norm);
  585. X    lght = (1.0 - capt) * inside (r, bll) + (capt * (double) shade (&er));
  586. X    }
  587. X    else
  588. X    lght = 0.0;
  589. X    rlev--;
  590. X     if (lght<0.0) lght=0.0;
  591. X     if (lght>255.0) lght=255.0;
  592. X    return (lght);
  593. X}
  594. X
  595. X
  596. X
  597. Xdouble  refk (nrm, in, ior)
  598. Xstruct vector  *nrm,
  599. X               *in;
  600. Xdouble  ior;
  601. X{
  602. X    double  dt,
  603. X            ln,
  604. X            li,
  605. X            ret;
  606. X
  607. X    ior = ior * ior;
  608. X    dt = DOT ((*nrm), (*in));
  609. X    ln = LN2 ((*nrm));
  610. X    li = LN2 ((*in));
  611. X    if (dt < 0)
  612. X    ret = (-dt - sqrt (dt * dt - ln * li * (1 - ior))) / ln;
  613. X    else
  614. X    ret = (-dt + sqrt (dt * dt - ln * li * (1 - ior))) / ln;
  615. X    return (ret);
  616. X}
  617. X
  618. Xdouble  getcapt (nrm, dr, ior)
  619. Xstruct vector  *nrm,
  620. X               *dr;
  621. Xdouble  ior;
  622. X{
  623. X    double  dt,
  624. X            cs1,
  625. X            cs2,
  626. X            p,
  627. X            s;
  628. X    dt = DOT ((*nrm), (*dr));
  629. X    dt = dt * dt / LN2 ((*nrm)) / LN2 ((*dr));
  630. X    cs1 = sqrt (dt);
  631. X    cs2 = sqrt (1.0 - (1.0 - dt) / ior);
  632. X    p = cs1 / (cs1 + ior * cs2);
  633. X    s = cs1 / (ior * cs1 + cs2);
  634. X    return (2.0 * (p * p + s * s));
  635. X}
  636. END_OF_refract.c
  637. if test 2965 -ne `wc -c <refract.c`; then
  638.     echo shar: \"refract.c\" unpacked with wrong size!
  639. fi
  640. # end of overwriting check
  641. fi
  642. if test -f rtd.h -a "${1}" != "-c" ; then 
  643.   echo shar: Will not over-write existing file \"rtd.h\"
  644. else
  645. echo shar: Extracting \"rtd.h\" \(434 characters\)
  646. sed "s/^X//" >rtd.h <<'END_OF_rtd.h'
  647. Xstruct color {
  648. Xint r;int g;int b;};
  649. X
  650. Xstruct vector {
  651. Xdouble x;
  652. Xdouble y;
  653. Xdouble z;
  654. Xdouble l;
  655. Xdouble xzl;} ;
  656. X
  657. Xstruct ray {
  658. Xstruct vector org;
  659. Xstruct vector dir;} ;
  660. X
  661. Xstruct sphere {
  662. Xstruct vector cent;
  663. Xdouble rad;} ;
  664. X
  665. Xstruct ball {
  666. Xstruct sphere s;
  667. Xdouble ior;
  668. Xdouble rfr;
  669. Xdouble rfl;
  670. Xdouble dif;
  671. Xdouble amb;
  672. X};
  673. X
  674. Xstruct mat {
  675. Xstruct vector x;  /* first !row! */
  676. Xstruct vector y;  /*second !row! */
  677. Xstruct vector z;}; /* third !row! */
  678. X
  679. END_OF_rtd.h
  680. if test 434 -ne `wc -c <rtd.h`; then
  681.     echo shar: \"rtd.h\" unpacked with wrong size!
  682. fi
  683. # end of overwriting check
  684. fi
  685. if test -f shade.c -a "${1}" != "-c" ; then 
  686.   echo shar: Will not over-write existing file \"shade.c\"
  687. else
  688. echo shar: Extracting \"shade.c\" \(3454 characters\)
  689. sed "s/^X//" >shade.c <<'END_OF_shade.c'
  690. X/*
  691. X * this subroutine does all the gritty work- it calculates 
  692. X * what shade each pixel should be. I like recursion.
  693. X */
  694. X#include <math.h>
  695. X#include "rtd.h"
  696. X#include "macros.h"
  697. X#include "extern.h"
  698. X
  699. Xint     shade (r)
  700. Xstruct ray *r;
  701. X{
  702. X    int     i,
  703. X            c,
  704. X            refract ();
  705. X    struct ray  refr;
  706. X    double  lght,
  707. X            x,
  708. X            y,
  709. X            z,
  710. X            l,
  711. X            k,
  712. X            dot (), find (), shadow ();
  713. X    int     sx,
  714. X            sy;
  715. X    double  stupid;
  716. X    struct vector   new,
  717. X                    norm;
  718. X    struct mat  trans;
  719. X    struct sphere   ss;
  720. X    if (++level <= LEVEL) {
  721. X    c = -1;
  722. X    l = HUGE;
  723. X/* get vector length and xz component for mt() */
  724. X    r -> dir.l = LEN (r -> dir);
  725. X    r -> dir.xzl = XZL (r -> dir);
  726. X/* make a transform matrix that rotates something in space so
  727. X   that the ray will be aligned with the x axis */
  728. X    mt (&(r -> dir), &trans);
  729. X
  730. X/* for starters we find out whether we hit anything. */
  731. X    for (i = 0; i < nob; i++) {
  732. X        ss.rad = bl[i] -> s.rad;
  733. X        SV (ss.cent, bl[i] -> s.cent, r -> org);
  734. X        if ((k = find (&trans, &ss)) > 0.0 && k < l) {
  735. X        c = i;
  736. X        l = k;
  737. X        }
  738. X    }
  739. X    if (c >= 0 && (l * trans.x.y + r -> org.y) > 0.0) {
  740. X                /* WE HIT SOMETHING */
  741. X        MV (l * trans.x.x, l * trans.x.y, l * trans.x.z, new);
  742. X        new.l=l;
  743. X/* move the new orgin of the ray to the intersection */
  744. X        AV (refr.org, new, r -> org);
  745. X        AV (r -> org, new, r -> org);
  746. X        MV (r -> dir.x, r -> dir.y, r -> dir.z, refr.dir);
  747. X/* get a normal vector for the intersection point */
  748. X        SV (norm, r -> org, bl[c] -> s.cent);
  749. X        norm.l=bl[c] ->s.rad;
  750. X
  751. X/* ambient lighting */
  752. X        lght = 200.0 * bl[c] -> amb;
  753. X
  754. X/* shaded lighting (diffuse). subroutine shadow is in find.c */
  755. X        if (bl[c] -> dif != 0.0) {
  756. X        SV (new, ls.cent, r -> org);
  757. X        new.l = LEN(new);
  758. X        if ((k = DOT (new, norm)) > 0.0)
  759. X            lght += bl[c] -> dif * shadow (&(r -> org)) * k / (new.l) / (norm.l);
  760. X        }
  761. X
  762. X/*reflection... easy */
  763. X        if (bl[c] -> rfl != 0.0) {
  764. X/* make the normal unit length */
  765. X        SCMLT ((1.0 / norm.l), norm);
  766. X/* get the length of the ray's component in the normal direction */
  767. X        stupid = 2.0 * DOT (norm, r -> dir);
  768. X        SCMLT (stupid, norm);
  769. X/* subtract double the normal component- !reflection! */
  770. X        SV (r -> dir, r -> dir, norm);
  771. X        lght += bl[c] -> rfl * (double) shade (r);
  772. X        }
  773. X
  774. X/* refraction. this is ugly, which is why I choose to deal with
  775. X   it in it's own subroutine which comes after this one */
  776. X        if (bl[c] -> rfr != 0.0) {
  777. X        lght += bl[c] -> rfr * (double) refract (&refr, bl[c]);
  778. X        }
  779. X
  780. X
  781. X
  782. X    }
  783. X    else {            /* hit no objects... */
  784. X        if ((r -> dir.y) < 0.0) {/* crosses floor */
  785. X        z = -(r -> org.y) / (r -> dir.y);
  786. X        (r -> org.x) += z * (r -> dir.x);
  787. X        (r -> org.z) += z * (r -> dir.z);
  788. X        (r -> org.y) = 0.0;
  789. X
  790. X        SV (new, ls.cent, r -> org);
  791. X        new.l = LEN(new);
  792. X        sx = (int) (r -> org.x / 1.5) % xsue;
  793. X        if (sx < 0)
  794. X            sx += xsue;
  795. X        sy = -(int) (r -> org.z / 1.5) % ysue;
  796. X        if (sy < 0)
  797. X            sy += ysue;
  798. X        lght = (sam * suzie[sx][sy] + 1.0 - sam) * (0.8 *
  799. X            shadow (&(r -> org)) * (new.y) / (new.l) + 40.0);
  800. X
  801. X
  802. X        }
  803. X        else {        /* check to see if it hit lightsource */
  804. X        SV (ss.cent, ls.cent, r -> org);
  805. X        ss.rad = ls.rad;
  806. X        if (find (&trans, &(ss.cent)) > 0.0)
  807. X            lght = 255;
  808. X        else
  809. X            lght = 0;
  810. X        }
  811. X    }
  812. X    }
  813. X/* to many levels return 0 cause it shouldn't matter */
  814. X    else
  815. X    lght = 0;
  816. X    level--;
  817. X    if (lght < 0.0)
  818. X    lght = 0.0;
  819. X    if (lght > 255.0)
  820. X    lght = 255.0;
  821. X    return ((int) lght);
  822. X}
  823. END_OF_shade.c
  824. if test 3454 -ne `wc -c <shade.c`; then
  825.     echo shar: \"shade.c\" unpacked with wrong size!
  826. fi
  827. # end of overwriting check
  828. fi
  829. if test -f support.c -a "${1}" != "-c" ; then 
  830.   echo shar: Will not over-write existing file \"support.c\"
  831. else
  832. echo shar: Extracting \"support.c\" \(834 characters\)
  833. sed "s/^X//" >support.c <<'END_OF_support.c'
  834. X/*
  835. X *    supportive subroutines...
  836. X */
  837. X
  838. X#include <math.h>
  839. X#include <stdio.h>
  840. X#include "rtd.h"
  841. X#include "extern.h"
  842. X
  843. X
  844. Xmt (vec, trans)
  845. Xstruct vector  *vec;
  846. Xstruct mat *trans;
  847. X{
  848. X    if (vec -> xzl == 0.0) {
  849. X    trans -> x.x = 0.0;
  850. X    trans -> x.y = 1.0;
  851. X    trans -> x.z = 0.0;
  852. X    trans -> y.x = -1.0;
  853. X    trans -> y.y = 0.0;
  854. X    trans -> y.z = 0.0;
  855. X    trans -> z.x = 0.0;
  856. X    trans -> z.y = 0.0;
  857. X    trans -> z.z = 1.0;
  858. X    }
  859. X    else {
  860. X    trans -> x.x = (vec -> x) / (vec -> l);
  861. X    trans -> x.y = (vec -> y) / (vec -> l);
  862. X    trans -> x.z = (vec -> z) / (vec -> l);
  863. X    trans -> y.x = -(vec -> x) * (vec -> y) / ((vec -> l) * (vec -> xzl));
  864. X    trans -> y.y = (vec -> xzl) / (vec -> l);
  865. X    trans -> y.z = -(vec -> z) * (vec -> y) / ((vec -> l) * (vec -> xzl));
  866. X    trans -> z.x = -(vec -> z) / (vec -> xzl);
  867. X    trans -> z.y = 0;
  868. X    trans -> z.z = (vec -> x) / (vec -> xzl);
  869. X    }
  870. X}
  871. END_OF_support.c
  872. if test 834 -ne `wc -c <support.c`; then
  873.     echo shar: \"support.c\" unpacked with wrong size!
  874. fi
  875. # end of overwriting check
  876. fi
  877. if test -f tracer.c -a "${1}" != "-c" ; then 
  878.   echo shar: Will not over-write existing file \"tracer.c\"
  879. else
  880. echo shar: Extracting \"tracer.c\" \(2624 characters\)
  881. sed "s/^X//" >tracer.c <<'END_OF_tracer.c'
  882. X
  883. X
  884. X/* tracer version 2.1 */
  885. X#include <stdio.h>
  886. X#include <math.h>
  887. X#include "rtd.h"
  888. X#include "macros.h"
  889. X
  890. X
  891. XFILE * fp;
  892. Xdouble  suzie[300][300],
  893. X        sam = 1.0;
  894. Xint     xsue,
  895. X        ysue;
  896. Xstruct ball *bl[150];
  897. Xint     level,
  898. X        nob;
  899. Xstruct sphere   ls;
  900. X
  901. Xmain (argc, argv)
  902. Xint     argc;
  903. Xchar  **argv;
  904. X{
  905. X    FILE * df, *texfile;
  906. X    static double   xco,
  907. X                    yco;
  908. X    struct ray  rr;
  909. X    struct vector   vp;
  910. X    double  x,
  911. X            y,
  912. X            z;
  913. X    int     i,
  914. X            in = 0,
  915. X            out = 0,
  916. X            tex = 0;
  917. X    int     c;
  918. X
  919. X/* command interp */
  920. X
  921. X    for (i = 1; i < argc; i++) {
  922. X    if (argv[i][0] != '-')
  923. X        booboo ("Options strt with a '-' bozo");
  924. X    c = argv[i][1];
  925. X
  926. X    switch (c) {
  927. X        case ('i'): 
  928. X        if (in)
  929. X            booboo ("Sorry, but you may only have one input file");
  930. X        in = 1;
  931. X        if ((i + 1) >= argc || argv[i + 1][0] == '-')/* no arg */
  932. X            df = stdin;
  933. X        else
  934. X            if ((df = fopen (argv[++i], "r")) == NULL)
  935. X            booboo ("input file not found");
  936. X        break;
  937. X        case ('o'): 
  938. X        if (out)
  939. X            booboo ("Sorry, but you may have only one output file");
  940. X        out = 1;
  941. X        if ((i + 1) >= argc || argv[i + 1][0] == '-')/* no arg */
  942. X            fp = stdout;
  943. X        else
  944. X            fp = fopen (argv[++i], "w");
  945. X        break;
  946. X        case ('s'): 
  947. X        if (tex)
  948. X            booboo ("Sorry, but you may have only one image file");
  949. X        if ((i + 1) >= argc || argv[i + 1][0] == '-')/* no arg */
  950. X            booboo ("-s requires an argument");
  951. X        tex = 1;
  952. X        if ((texfile = fopen (argv[++i], "r")) == NULL)
  953. X            booboo ("image file not found");
  954. X        break;
  955. X        booboo ("this line shouldn't do anything");
  956. X        case ('S'): 
  957. X        if (argv[i][2] < '0' || argv[i][2] > '9'){
  958. Xprintf("%c\n",argv[i][2]);
  959. X            booboo ("-S needs a numerical argument");}
  960. X        sam = atof (&(argv[i][2]));
  961. X        break;
  962. X        default: 
  963. X        booboo ("Unrecognized option. Better try again");
  964. X    }
  965. X    }
  966. X
  967. X
  968. X    if (!in)
  969. X    if ((df = fopen ("bdata.i", "r")) == NULL)
  970. X        booboo ("bdata.i not found");
  971. X    if (!out)
  972. X    fp = fopen ("data.dis", "w");
  973. X    if (!tex)
  974. X    if ((texfile = fopen ("pat.def", "r")) == NULL)
  975. X        booboo ("pat.def not found");
  976. X
  977. X
  978. X
  979. X    nob = g_bal (df);
  980. X    g_bod (texfile);
  981. X
  982. X
  983. X
  984. X    MV (95.0, 140.0, -200.0, vp);
  985. X    MV (0.0, 900.0, 0.0, ls.cent);
  986. X    ls.rad = 40;
  987. X    fprintf (fp, "%d %d\n", (int) ((XMAX - XMIN) * SCALE +0.9999999), (int) ((YMAX - YMIN) * SCALE +0.9999999));
  988. X
  989. X    for (yco = YMAX * SCALE; yco > YMIN * SCALE; yco--)
  990. X    for (xco = XMIN * SCALE; xco < XMAX * SCALE; xco++) {
  991. X        MV (xco / SCALE, yco / SCALE, 0.0, rr.org);
  992. X        SV (rr.dir, rr.org, vp);
  993. X        fprintf (fp, "%c", shade (&rr));
  994. X    }
  995. X}
  996. X
  997. Xbooboo (str)
  998. Xchar   *str; {
  999. X    printf ("%s\n", str);
  1000. X    exit (-1);
  1001. X}
  1002. END_OF_tracer.c
  1003. if test 2624 -ne `wc -c <tracer.c`; then
  1004.     echo shar: \"tracer.c\" unpacked with wrong size!
  1005. fi
  1006. # end of overwriting check
  1007. fi
  1008. echo shar: End of shell archive.
  1009. exit 0
  1010.